C# Winform重绘按钮 您所在的位置:网站首页 winform 按钮圆角 C# Winform重绘按钮

C# Winform重绘按钮

#C# Winform重绘按钮| 来源: 网络整理| 查看: 265

目的:学习了解GDI绘制、在复刻Winform按钮,实现圆角边框/矩形边框/无边框,以及悬停、点击等事件

引申:可根据按钮的重绘,拓展到输入框的圆角功能

一、环境

VS2022

新建操作:1、新建->项目->Window窗口应用(.NET Framework)->创建(取个自己喜欢的命名)

2、对于新建的项目 右键 添加->类->添加(取个自己喜欢的命名)

二、代码

using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.IO; using System.Windows.Forms; namespace ControlTest { internal class buttonRY : System.Windows.Forms.Control { private GraphicsPath g; private Rectangle cr; // 客户端矩形区域 private ControlState ControlState = ControlState.Normal; //控件状态 private Color LocalColorRY { get; set; } //控件当前的背景 public buttonRY() { //画面闪烁问题与双缓冲技术 this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true); this.UpdateStyles(); } #region 自定义面板属性 private Color _BackColor = Color.FromArgb(253, 253, 253); //#fdfdfd //[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [Description("背景颜色"), Category("自定义"), Browsable(true)] public Color BackColorRY { get { return _BackColor; } set { _BackColor = value; this.Refresh(); } } private Color _HoverColor = Color.FromArgb(224, 238, 249); // #e0eef9 [Description("悬停时的颜色"), Category("自定义"), Browsable(true)] public Color HoverColorRY { get { return _HoverColor; } set { _HoverColor = value; this.Refresh(); } } private Color _DownColor = Color.FromArgb(204, 228, 247); //#cce4f7 [Description("按下时的颜色"), Category("自定义"), Browsable(true)] public Color DownColorRY { get { return _DownColor; } set { _DownColor = value; this.Refresh(); } } private Color _ForeColor = Color.FromArgb(0, 0, 0); [Description("字体颜色"), Category("自定义"), Browsable(true)] public Color ForeColorRY { get { return _ForeColor; } set { _ForeColor = value; this.Refresh(); } } private Font _Font = new Font("宋体", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134))); [Description("字体"), Category("自定义"), Browsable(true)] public Font FontRY { get { return _Font; } set { _Font = value; this.Refresh(); } } private ContentAlignment _TextAlign = ContentAlignment.MiddleCenter; [Description("显示文本的对齐方式"), Category("自定义"), Browsable(true)] public ContentAlignment TextAlignRY { get { return _TextAlign; } set { _TextAlign = value; } } private bool _isBorder = true; [Description("设置为true时,边框存在"), Category("自定义"), Browsable(true)] public bool IsBorderRY { get { return _isBorder; } set { _isBorder = value; this.Refresh(); } } private BorderType _borderType = BorderType.Fillet; [Description("IsBorderRY为True,设置边框类型 圆角|方形|无"), Category("自定义"), Browsable(true)] public BorderType BorderTypeRY { get { return _borderType; } set { _borderType = value; this.Refresh(); } } private int _filletSize = 5; [Description("当边框类型为圆角时,设置圆角大小"), Category("自定义"), Browsable(true)] public int FilletSizeRY { get { return _filletSize; } set { _filletSize = value; this.Refresh(); } } private Color _BorderColor = Color.FromArgb(208, 208, 208); //#d0d0d0 [Description("边框颜色"), Category("自定义"), Browsable(true)] public Color BorderColorRY { get { return _BorderColor; } set { _BorderColor = value; this.Refresh(); } } private int _BorderWidth = 1; [Description("边框粗细"), Category("自定义"), Browsable(true)] public int BorderWidthRY { get { return _BorderWidth; } set { _BorderWidth = value; this.Refresh(); this.Refresh(); } } #endregion #region 绘制控件 /// /// 绘制与填充边框 /// /// private void DrawBorderRY(PaintEventArgs e) { // 锯齿 e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; //e.Graphics.SmoothingMode = SmoothingMode.HighQuality; e.Graphics.CompositingQuality = CompositingQuality.HighQuality; e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; this.BackColor = this.Parent.BackColor; //相对父类控件透明 cr = this.ClientRectangle; //获取客户端区域 cr.Width -= 1; //修正 cr.Height -= 1; //g = new GraphicsPath(); switch(ControlState) //根据当前控件状态,决定填充背景颜色 { case ControlState.Normal: LocalColorRY = BackColorRY; break; case ControlState.Pressed: LocalColorRY = DownColorRY; break; case ControlState.Hover: LocalColorRY = HoverColorRY; break; } Trace.WriteLine(ControlState.ToString()); switch (BorderTypeRY) //边框绘制与填充 { case BorderType.Fillet: g = FilletRectangleRY(); e.Graphics.FillPath(new SolidBrush(LocalColorRY), g); // 填充区域 if (IsBorderRY) e.Graphics.DrawPath(new Pen(BorderColorRY, BorderWidthRY), g); // 绘制边框 break; case BorderType.Rectangle: g = RectangleRY(); e.Graphics.FillPath(new SolidBrush(LocalColorRY), g); // 填充区域 if (IsBorderRY) e.Graphics.DrawPath(new Pen(BorderColorRY, BorderWidthRY), g); break; case BorderType.None: g = RectangleRY(); e.Graphics.FillPath(new SolidBrush(LocalColorRY), g); // 填充区域 break; } //g.AddRectangle(this.ClientRectangle); //当你创建一个W,H 控件时,内部(0,0,W, H)则是ClientRectangle } /// /// 绘制文字 /// /// private void DrawString(PaintEventArgs e) { SizeF sizeF = e.Graphics.MeasureString(this.Text, FontRY); //text 尺寸 if (this.Text != "") { switch (TextAlignRY) { case ContentAlignment.TopLeft:// 上左 e.Graphics.DrawString(this.Text, FontRY, new SolidBrush(ForeColorRY), 0, 0); break; case ContentAlignment.TopCenter:// 上居中 e.Graphics.DrawString(this.Text, FontRY, new SolidBrush(ForeColorRY), this.Width / 2 - sizeF.Width / 2, 0); break; case ContentAlignment.TopRight:// 上右 e.Graphics.DrawString(this.Text, FontRY, new SolidBrush(ForeColorRY), this.Width - sizeF.Width, 0); break; case ContentAlignment.MiddleLeft://左居中 e.Graphics.DrawString(this.Text, FontRY, new SolidBrush(ForeColorRY), 0, this.Height / 2 - sizeF.Height / 2); break; case ContentAlignment.MiddleCenter:// 居中 e.Graphics.DrawString(this.Text, FontRY, new SolidBrush(ForeColorRY), this.Width / 2 - sizeF.Width / 2, this.Height / 2 - sizeF.Height / 2); break; case ContentAlignment.MiddleRight:// 右居中 e.Graphics.DrawString(this.Text, FontRY, new SolidBrush(ForeColorRY), this.Width - sizeF.Width, this.Height / 2 - sizeF.Height / 2); break; case ContentAlignment.BottomLeft:// 下左 e.Graphics.DrawString(this.Text, FontRY, new SolidBrush(ForeColorRY), 0, this.Height - sizeF.Height); break; case ContentAlignment.BottomCenter:// 下居中 e.Graphics.DrawString(this.Text, FontRY, new SolidBrush(ForeColorRY), this.Width / 2 - sizeF.Width / 2, this.Height - sizeF.Height); break; case ContentAlignment.BottomRight:// 下右 e.Graphics.DrawString(this.Text, FontRY, new SolidBrush(ForeColorRY), this.Width - sizeF.Width, this.Height - sizeF.Height); break; } } } /// /// 圆角矩形路径 /// /// private GraphicsPath FilletRectangleRY() { GraphicsPath path = new GraphicsPath(); //上边 path.AddLine(new PointF(cr.X + FilletSizeRY, cr.Y), new PointF(cr.Right - FilletSizeRY, cr.Y)); //右上角 path.AddArc(cr.Right - FilletSizeRY * 2, cr.Y, FilletSizeRY * 2, FilletSizeRY * 2, 270, 90); //右边 path.AddLine(new PointF(cr.Right, cr.Y + FilletSizeRY), new PointF(cr.Right, cr.Bottom - FilletSizeRY)); //右下角 path.AddArc(cr.Right - FilletSizeRY * 2, cr.Bottom - FilletSizeRY * 2, FilletSizeRY * 2, FilletSizeRY * 2, 0, 90); //下边 path.AddLine(new PointF(cr.X + FilletSizeRY, cr.Bottom), new PointF(cr.Right - FilletSizeRY, cr.Bottom)); //左下角 path.AddArc(cr.X, cr.Bottom - FilletSizeRY * 2, FilletSizeRY * 2, FilletSizeRY * 2, 90, 90); //左边 path.AddLine(new PointF(cr.X, cr.Y + FilletSizeRY), new PointF(cr.X, cr.Bottom - FilletSizeRY)); //左上角 path.AddArc(cr.X, cr.Y, FilletSizeRY * 2, FilletSizeRY * 2, 180, 90); return path; } // 矩形路径 private GraphicsPath RectangleRY() { GraphicsPath path = new GraphicsPath(); path.AddRectangle(cr); return path; } #endregion #region 重写事件 protected override void OnMouseHover(EventArgs e) { base.OnMouseHover(e); ControlState = ControlState.Hover; this.Invalidate(); //控件发送绘制消息 Trace.WriteLine("悬停"); } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); ControlState = ControlState.Normal; this.Invalidate(); Trace.WriteLine("离开"); } protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); if (e.Button == MouseButtons.Left && e.Clicks == 1) { ControlState = ControlState.Pressed; this.Invalidate(); Trace.WriteLine("按下"); } } protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); if (e.Button == MouseButtons.Left && e.Clicks == 1) { //if (this.ClientRectangle.Contains(e.Location)) // 包含检测,其实不一定需要 //{ // ControlState = ControlState.Normal; //} ControlState = ControlState.Hover; this.Invalidate(); Trace.WriteLine("松开"); } } protected override void OnEnter(EventArgs e) { base.OnEnter(e); //this.Focus(); Trace.WriteLine("焦点"); this.Invalidate(); } protected override void OnPaint(PaintEventArgs e) { try { DrawBorderRY(e); DrawString(e); //e.Graphics.Dispose(); //注意不要提前释放 } catch (Exception ex) { Trace.WriteLine(ex); } base.OnPaint(e); } #endregion } enum BorderType { Fillet, Rectangle, None } //边框类型枚举 enum ControlState { Hover, Normal, Pressed, Focus }//控件状态枚举 }

3、使用

生成解决方案后,工具栏处将出现自定义的的控件,然后与其他控件一样正常使用。

4、结语

根据上面内容,我们可以很自然的可以通过自定义 绘制路径,来实现各种奇奇怪怪的边框;同时其他控件也可由以上灵感沿伸。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有